home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 3 / Gold Medal Software - Volume 3 (Gold Medal) (1994).iso / bbsutils / smb_110a.arj / QWK2SMB.C < prev    next >
C/C++ Source or Header  |  1994-03-22  |  8KB  |  296 lines

  1. /* QWK2SMB.C */
  2.  
  3. /* Converts QWK packet to to SMB formatted message bases */
  4.  
  5. /* The intention of this source code is an example of how to use the SMBLIB */
  6. /* library functions to access an SMB format message base.                    */
  7.  
  8. /* This program and source code are freeware. May be used in part or whole    */
  9. /* for any purpose without consent or notification of Digital Dynamics.     */
  10.  
  11. /* Digital Dynamics does request that developers that release products that */
  12. /* support the SMB format notify Digital Dynamics so the implementation     */
  13. /* and contact chapters in the technical specification may be updated.        */
  14.  
  15. #include "smblib.h"
  16. #include "crc32.h"
  17. #include <dos.h>
  18.  
  19. char sbbs[128];
  20.  
  21. /****************************************************************************/
  22. /* Updates 16-bit "rcrc" with character 'ch'                                */
  23. /****************************************************************************/
  24. void ucrc16(uchar ch, ushort *rcrc) {
  25.     ushort i, cy;
  26.     uchar nch=ch;
  27.  
  28. for (i=0; i<8; i++) {
  29.     cy=*rcrc & 0x8000;
  30.     *rcrc<<=1;
  31.     if (nch & 0x80) *rcrc |= 1;
  32.     nch<<=1;
  33.     if (cy) *rcrc ^= 0x1021; }
  34. }
  35.  
  36. /****************************************************************************/
  37. /* Returns 16-crc of string (not counting terminating NULL)                 */
  38. /****************************************************************************/
  39. ushort crc16(char *str)
  40. {
  41.     int     i=0;
  42.     ushort    crc=0;
  43.  
  44. ucrc16(0,&crc);
  45. while(str[i])
  46.     ucrc16(str[i++],&crc);
  47. ucrc16(0,&crc);
  48. ucrc16(0,&crc);
  49. return(crc);
  50. }
  51.  
  52.  
  53. /****************************************************************************/
  54. /* Truncates white-space chars off end of 'str' and terminates at first tab */
  55. /****************************************************************************/
  56. void truncsp(char *str)
  57. {
  58.     char c;
  59.  
  60. str[strcspn(str,"\t")]=0;
  61. c=strlen(str);
  62. while(c && (uchar)str[c-1]<=' ') c--;
  63. str[c]=0;
  64. }
  65.  
  66. /****************************************************************************/
  67. /* Converts an ASCII Hex string into an ulong                       */
  68. /****************************************************************************/
  69. ulong ahtoul(char *str)
  70. {
  71.     ulong l,val=0;
  72.  
  73. while((l=(*str++)|0x20)!=0x20)
  74.     val=(l&0xf)+(l>>6&1)*9+val*16;
  75. return(val);
  76. }
  77.  
  78. /****************************************************************************/
  79. /* Returns the length of the file in 'filespec'                             */
  80. /****************************************************************************/
  81. long flength(char *filespec)
  82. {
  83.     struct ffblk f;
  84.  
  85. if(findfirst(filespec,&f,0)==0)
  86.     return(f.ff_fsize);
  87. return(-1L);
  88. }
  89.  
  90. /****************************************************************************/
  91. /* Returns the FidoNet address kept in str as ASCII.                        */
  92. /****************************************************************************/
  93. fidoaddr_t atofaddr(char *str)
  94. {
  95.     char *p;
  96.     fidoaddr_t addr;
  97.  
  98. addr.zone=addr.net=addr.node=addr.point=0;
  99. if((p=strchr(str,':'))!=NULL) {
  100.     addr.zone=atoi(str);
  101.     addr.net=atoi(p+1); }
  102. else {
  103.     addr.zone=1;
  104.     addr.net=atoi(str); }
  105. if(!addr.zone)                /* no such thing as zone 0 */
  106.     addr.zone=1;
  107. if((p=strchr(str,'/'))!=NULL)
  108.     addr.node=atoi(p+1);
  109. else {
  110.     addr.net=1;
  111.     addr.node=atoi(str); }
  112. if((p=strchr(str,'.'))!=NULL)
  113.     addr.point=atoi(p+1);
  114. return(addr);
  115. }
  116.  
  117.  
  118. int main(int argc, char **argv)
  119. {
  120.     uchar    *p,str[128],from[128],to[128],subj[128],block[128],*buf;
  121.     ushort    xlat;
  122.     ushort    i,j,k,msgs,total;
  123.     ulong    l,m,length,size,crc;
  124.     FILE    *qwk;
  125.     struct    date date;
  126.     struct    time curtime;
  127.     smbmsg_t    msg;
  128.     smbstatus_t status;
  129.  
  130. if(argc<2) {
  131.     printf("usage: qwk2smb <qwk_dir>\r\n");
  132.     exit(1); }
  133.  
  134. sprintf(str,"%s\\MESSAGES.DAT",argv[1]);
  135. if((qwk=fopen(str,"rb"))==NULL) {
  136.     printf("error opening %s\n",str);
  137.     exit(1); }
  138.  
  139. size=filelength(fileno(qwk));
  140. smb_file[0]=0;
  141.  
  142. for(l=128,i=1,msgs=total=1;l<size;l+=i*128) {
  143.     fseek(qwk,l,SEEK_SET);
  144.     if(!fread(block,1,128,qwk))
  145.         break;
  146.     i=atoi(block+116);    /* i = number of 128 byte records */
  147.     if(i<2) {
  148.         i=1;
  149.         continue; }
  150.  
  151.     j=(ushort)block[123]|(((ushort)block[124])<<8);  /* conference number */
  152.  
  153.     if(strcmp(smb_file,itoa(j,str,10))) {         /* changed conference */
  154.         fclose(sdt_fp);
  155.         fclose(shd_fp);
  156.         fclose(sid_fp);
  157.         strcpy(smb_file,str);
  158.         printf("\nConference #%s\n",str);
  159.         msgs=1;
  160.         k=smb_open(10);
  161.         if(k) {
  162.             printf("smb_open returned %d\n",k);
  163.             exit(1); }
  164.         if(!filelength(fileno(shd_fp)))         /* new conference */
  165.             smb_create(2000,2000,0,10); }
  166.  
  167.     smb_getstatus(&status);       // Initialized for first call to smb_addcrc()
  168.  
  169.     printf("%u (total=%u)\r",msgs,total);
  170.  
  171.     /*****************************/
  172.     /* Initialize the SMB header */
  173.     /*****************************/
  174.  
  175.     memset(&msg,0,sizeof(smbmsg_t));
  176.     memcpy(msg.hdr.id,"SHD\x1a",4);
  177.     msg.hdr.version=SMB_VERSION;
  178.  
  179.     /**************************/
  180.     /* Convert the QWK header */
  181.     /**************************/
  182.  
  183.     if(block[0]=='*' || block[0]=='+')
  184.         msg.idx.attr|=MSG_PRIVATE;
  185.     if(block[0]=='*' || block[0]=='-' || block[0]=='`')
  186.         msg.idx.attr|=MSG_READ;
  187.     msg.hdr.attr=msg.idx.attr;
  188.  
  189.     date.da_mon=((block[8]&0xf)*10)+(block[9]&0xf);
  190.     date.da_day=((block[11]&0xf)*10)+(block[12]&0xf);
  191.     date.da_year=((block[14]&0xf)*10)+(block[15]&0xf)+1900;
  192.     curtime.ti_hour=((block[16]&0xf)*10)+(block[17]&0xf);
  193.     curtime.ti_min=((block[19]&0xf)*10)+(block[20]&0xf);
  194.     curtime.ti_sec=0;
  195.     msg.hdr.when_written.time=dostounix(&date,&curtime);
  196.     msg.hdr.when_written.zone=PST;         /* set to local time zone */
  197.     msg.hdr.when_imported.time=time(NULL);
  198.     msg.hdr.when_imported.zone=PST;      /* set to local time zone */
  199.  
  200.     sprintf(to,"%25.25s",block+21);     /* To user */
  201.     truncsp(to);
  202.     smb_hfield(&msg,RECIPIENT,strlen(to),to);
  203.     strlwr(to);
  204.     msg.idx.to=crc16(to);
  205.  
  206.     sprintf(from,"%25.25s",block+46);   /* From user */
  207.     truncsp(from);
  208.     smb_hfield(&msg,SENDER,strlen(from),from);
  209.     strlwr(from);
  210.     msg.idx.from=crc16(from);
  211.  
  212.     sprintf(subj,"%25.25s",block+71);   /* Subject */
  213.     truncsp(subj);
  214.     smb_hfield(&msg,SUBJECT,strlen(subj),subj);
  215.     strlwr(subj);
  216.     msg.idx.subj=crc16(subj);
  217.  
  218.     /********************************/
  219.     /* Convert the QWK message text */
  220.     /********************************/
  221.  
  222.     length=0;
  223.     if((buf=MALLOC((i-1)*128*2))==NULL) {
  224.         printf("memory allocation error\n");
  225.         exit(1); }
  226.     for(j=1;j<i;j++) {
  227.         if(!fread(block,1,128,qwk))
  228.             break;
  229.         for(k=0;k<128;k++) {
  230.             if(block[k]==0)
  231.                 continue;
  232.             if(block[k]==0xE3) {       /* expand 0xe3 to crlf */
  233.                 buf[length++]=CR;
  234.                 buf[length++]=LF;
  235.                 continue; }
  236.             buf[length++]=block[k]; } }
  237.  
  238.     while(length && buf[length-1]<=SP) length--; /* remove trailing garbage */
  239.  
  240.     /*****************/
  241.     /* Calculate CRC */
  242.     /*****************/
  243.  
  244.     crc=0xffffffffUL;
  245.     for(m=0;m<length;m++)
  246.         crc=ucrc32(buf[m],crc);
  247.     crc=~crc;
  248.  
  249.     /*******************/
  250.     /* Check for dupes */
  251.     /*******************/
  252.  
  253.     j=smb_addcrc(status.max_crcs,crc,10);
  254.     if(j) {
  255.         if(j==1) {
  256.             printf("\nDuplicate message\n");
  257.             smb_freemsgmem(msg);
  258.             FREE(buf);
  259.             continue; }
  260.         printf("smb_addcrc returned %d\n",j);
  261.         exit(1); }
  262.  
  263.     /*************************************/
  264.     /* Write SMB message header and text */
  265.     /*************************************/
  266.  
  267.     length+=2;    /* for translation string */
  268.  
  269.     if(smb_open_da(10)) {
  270.         printf("error opening %s.SDA\n",smb_file);
  271.         exit(1); }
  272.     msg.hdr.offset=smb_fallocdat(length,1);
  273.     fclose(sda_fp);
  274.     if(msg.hdr.offset && msg.hdr.offset<1L) {
  275.         printf("error %ld allocating blocks\r\n",msg.hdr.offset);
  276.         exit(1); }
  277.     fseek(sdt_fp,msg.hdr.offset,SEEK_SET);
  278.     xlat=XLAT_NONE;
  279.     fwrite(&xlat,2,1,sdt_fp);
  280.     fwrite(buf,length,1,sdt_fp);
  281.  
  282.     smb_dfield(&msg,TEXT_BODY,length);
  283.  
  284.     k=smb_addmsghdr(&msg,&status,1,10);
  285.     if(k) {
  286.         printf("smb_addmsghdr returned %d\n",k);
  287.         exit(1); }
  288.     smb_freemsgmem(msg);
  289.     FREE(buf);
  290.     msgs++;
  291.     total++; }
  292.  
  293. return(0);
  294. }
  295.  
  296.